package handlers

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"jz/config"
	"jz/models"
	"net/http"
	"strings"
)

type TransactionHandler struct {
	db        *sql.DB
	cfg       *config.Config
	tableName string
}

func NewTransactionHandler(db *sql.DB, cfg *config.Config, tableName string) *TransactionHandler {
	return &TransactionHandler{
		db:        db,
		cfg:       cfg,
		tableName: tableName,
	}
}

// TransactionHandler 结构体中添加 GetDB 方法
func (h *TransactionHandler) GetDB() *sql.DB {
    return h.db
}

func (h *TransactionHandler) HandleApiSave(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		writeJSON(w, models.CreateResponse(false, "方法不允许"), http.StatusMethodNotAllowed)
		return
	}

	var request models.TransactionRequest
	if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
		writeJSON(w, models.CreateResponse(false, "请求格式错误"), http.StatusBadRequest)
		return
	}

	// 验证数据
	yearmonth := request.Month
	if yearmonth == "" || len(request.Transactions) == 0 {
		writeJSON(w, models.CreateResponse(false, "请求参数不完整"), http.StatusBadRequest)
		return
	}

	// 分割年月
	temp := strings.Split(yearmonth, "-")
	if len(temp) != 2 {
		writeJSON(w, models.CreateResponse(false, "月份格式错误"), http.StatusBadRequest)
		return
	}

	// 打印日志
	fmt.Printf("接收到%d条交易记录\n", len(request.Transactions))
	fmt.Printf("月份: %s\n", request.Month)

	// 开启事务
	tx, err := h.db.Begin()
	if err != nil {
		writeJSON(w, models.CreateResponse(false, "服务器处理错误: "+err.Error()), http.StatusInternalServerError)
		return
	}
	defer tx.Rollback()

	// 获取表配置
	tableConfig := h.cfg.Tables.Transactions
	if len(tableConfig.Columns) == 0 {
		writeJSON(w, models.CreateResponse(false, "表结构配置不存在"), http.StatusInternalServerError)
		return
	}

	// 动态生成SQL语句
	var columnNames []string
	var placeholders []string
	var values []interface{}

	for _, t := range request.Transactions {
		// 确保类型字段正确，只接受 "income" 或 "expense"
		transactionType := strings.ToLower(t.Type)
		if transactionType != "income" && transactionType != "expense" {
			// 默认设置为支出
			transactionType = "expense"
		}
		
		for _, col := range tableConfig.Columns {
			switch col.Name {
			case "money":
				columnNames = append(columnNames, col.Name)
				placeholders = append(placeholders, "?")
				values = append(values, t.Amount)
			case "type":
				columnNames = append(columnNames, col.Name)
				placeholders = append(placeholders, "?")
				values = append(values, transactionType) // 使用验证后的类型
			case "sub_type":
				columnNames = append(columnNames, col.Name)
				placeholders = append(placeholders, "?")
				values = append(values, t.Category)
			case "year":
				columnNames = append(columnNames, col.Name)
				placeholders = append(placeholders, "?")
				values = append(values, temp[0])
			case "month":
				columnNames = append(columnNames, col.Name)
				placeholders = append(placeholders, "?")
				values = append(values, temp[1])
			case "name", "remark":
				columnNames = append(columnNames, col.Name)
				placeholders = append(placeholders, "?")
				values = append(values, t.Remark)
			case "created_time", "create_time":
				columnNames = append(columnNames, col.Name)
				placeholders = append(placeholders, "STR_TO_DATE(?, '%Y-%m-%d %H:%i:%s')")
				values = append(values, fmt.Sprintf("%s %s", t.Date, t.Time))
			}
		}

		// 构建SQL语句
		sql := fmt.Sprintf(
			"INSERT INTO %s (%s) VALUES (%s)",
			h.tableName, // 使用保存的表名
			strings.Join(columnNames, ", "),
			strings.Join(placeholders, ", "),
		)

		// 打印SQL语句
		fmt.Printf("执行SQL: %s\n参数值: %v\n", sql, values)

		// 执行SQL
		_, err = tx.Exec(sql, values...)
		if err != nil {
			// 打印详细的错误日志
			fmt.Printf("SQL执行错误:\nSQL: %s\n参数值: %v\n错误信息: %v\n", sql, values, err)
			writeJSON(w, models.CreateResponse(false, "服务器处理错误: "+err.Error()), http.StatusInternalServerError)
			return
		}

		// 清空slice以准备下一条记录
		columnNames = columnNames[:0]
		placeholders = placeholders[:0]
		values = values[:0]
	}

	// 提交事务
	if err := tx.Commit(); err != nil {
		writeJSON(w, models.CreateResponse(false, "服务器处理错误: "+err.Error()), http.StatusInternalServerError)
		return
	}

	writeJSON(w, models.CreateResponse(true, "数据接收成功"), http.StatusOK)
}

func writeJSON(w http.ResponseWriter, data interface{}, status int) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(status)
	json.NewEncoder(w).Encode(data)
}
